As we saw in the previous notebook, building standalone applications of simple programs is quite easy.
cx_Freeze analyses the program for required dependencies and packs everything into a folder together with a Python interpreter and an executable.
For more advanced programs however it can be a nightmare to get all required depedencies included.
Here is an example with PyQt4, Matplotlib and Numpy
In [5]:
%%file "my_qt_program.py"
import sys
from PyQt4 import QtGui
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.pyplot as plt
import numpy as np
class QtWindow(QtGui.QDialog):
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent)
self.setWindowIcon(QIcon('test.ico'))
self.figure = plt.figure()
self.canvas = FigureCanvas(self.figure)
self.button = QtGui.QPushButton('Plot')
self.button.clicked.connect(self.plot)
# set the layout
layout = QtGui.QVBoxLayout()
layout.addWidget(self.canvas)
layout.addWidget(self.button)
self.setLayout(layout)
def plot(self):
''' plot some random stuff '''
data = [np.random() for i in range(25)]
ax = self.figure.add_subplot(111)
ax.hold(False)
ax.plot(data, '*-')
self.canvas.draw()
@staticmethod
def run():
app = QtGui.QApplication(sys.argv)
main = QtWindow()
main.show()
sys.exit(app.exec_())
if __name__ == '__main__':
QtWindow.run()
In [3]:
from my_qt_program import QtWindow
QtWindow.run()
In [8]:
"""
Run this function if icons are not loaded
"""
from PyQt4 import QtCore
import sys
import os
app = QtCore.QCoreApplication(sys.argv)
qt_library_path = QtCore.QCoreApplication.libraryPaths()
imageformats_path = None
for path in qt_library_path:
if os.path.exists(os.path.join(str(path), 'imageformats')):
imageformats_path = os.path.join(str(path), 'imageformats')
local_imageformats_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'imageformats')
local_imageformats_path = os.path.join(os.getcwd(), 'imageformats')
if not os.path.exists(local_imageformats_path):
os.mkdir(local_imageformats_path)
for file in glob.glob(os.path.join(imageformats_path, '*')):
shutil.copy(file, os.path.join(local_imageformats_path, os.path.basename(file)))
In [6]:
%%file "setup.py"
from cx_Freeze import setup, Executable
import matplotlib
build_exe_options = {
"includes" : ["sip", "matplotlib.backends.backend_tkagg"],
"include_files": ['imageformats/', (matplotlib.get_data_path(), "mpl-data")]
}
setup(
name = "my_qt_program",
version="1.0.0",
options = { "build_exe": build_exe_options},
executables = [Executable("my_qt_program.py", base='Win32GUI', icon='test.ico')])
In [4]:
import os
print (os.system("python setup.py build"))
In [3]:
import build_cx_exe
from build_cx_exe import *
build_cx_exe.build_exe('my_qt_program.py', "1.0.0", modules=[PYQT4, SCIPY, MATPLOTLIB, NUMPY])
Now the application is build. You can find it in "./build/exe.../my_qt_program.exe
As inspiration you can have a look at build_cx_exe.py
It automates the process and is invoked by one line,
from build_cx_exe import build_exe, PYQT4, MATPLOTLIB, NUMPY
build_exe('my_qt_program.py', "1.0.0", modules=[PYQT4, MATPLOTLIB, NUMPY], icon='test.ico')
but it does only work on some systems, with some modules and cannot be used from ipython notebooks